package com.gmss.crawler.module.integrity.integritycase.controller;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gmss.crawler.constants.Base;
import com.gmss.crawler.constants.Constants;
import com.gmss.crawler.enums.AcademicianEnum;
import com.gmss.crawler.enums.CommonEnum;
import com.gmss.crawler.module.integrity.integritycase.domain.IntegrityCase;
import com.gmss.crawler.module.integrity.integritycase.service.IIntegrityCaseService;
import com.gmss.crawler.module.person.domain.PersonInfo;
import com.gmss.crawler.module.person.service.IPersonInfoService;
import com.gmss.crawler.service.IntegrityCaseCrawlerService;
import com.gmss.crawler.task.IntegrityCaseTask;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;


/**
 * <p>
 * 科研诚信案件表 前端控制器
 * </p>
 *
 * @author Auto-generator
 * @since 2021-11-25
 */
@RestController
@RequestMapping("/integrityCase")
public class IntegrityCaseController extends Base {


    @Resource
    private IIntegrityCaseService iIntegrityCaseService;

    @Resource
    private IntegrityCaseTask integrityCaseTask;

    @Resource
    private IPersonInfoService iPersonInfoService;

    @Resource
    private IntegrityCaseCrawlerService integrityCaseCrawlerService;

    @PostMapping("/integrityCaseInputExcel")
    public String integrityCaseInputExcel(@RequestBody String str) {

        if (StringUtils.isBlank(str))
            return respJson(CommonEnum.PARAM_NULL_ERROR);

        Map<String, Object> map = JSON.parseObject(str);
        if (MapUtils.isEmpty(map))
            return respJson(CommonEnum.PARAM_NULL_ERROR);

        if (!map.containsKey("filePath") || StringUtils.isBlank(map.get("filePath").toString())) {
            return respJson(CommonEnum.PARAM_ERROR, "导出excel的路径不能为空！");
        }

        if (!map.containsKey("fileName") || StringUtils.isBlank(map.get("fileName").toString())) {
            return respJson(CommonEnum.PARAM_ERROR, "导出excel的文件名称不能为空！");
        } else {
            String fileName = map.get("fileName").toString();
            String fileNamesuffix = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
            if (!StringUtils.equalsAny(fileNamesuffix, "xlsx", "xls")) {
                return respJson(CommonEnum.PARAM_ERROR, "导出excel的文件名称后缀不正确，后缀应该为xlsx或xls ");
            }
        }


        List<IntegrityCase> integrityCaseList = null;
        List<PersonInfo> personInfoList = null;
        try {
            String filePath = map.get("filePath").toString() + File.separator + map.get("fileName").toString();
            integrityCaseList = iIntegrityCaseService.parseIntegrityCaseExcel(filePath);
            personInfoList = iIntegrityCaseService.parsePersonInfoIntegrityCaseExcel(filePath);
        } catch (IOException e) {
            log.error("integrityCaseInputExcel 科研诚信案件解析Excel - Exception：{}", e);
            return respJson(CommonEnum.ERROR, "科研诚信案件解析异常！");
        }

        Map<Long, List<PersonInfo>> personInfoMap = new LinkedHashMap<>();
        if (CollectionUtils.isNotEmpty(personInfoList)) {
            for (PersonInfo personInfo : personInfoList) {
                List<PersonInfo> personInfoTopyList2 = new ArrayList<>();
                personInfoTopyList2.add(personInfo);
                if (personInfoMap.containsKey(personInfo.getCaseId())) {
                    List<PersonInfo> personList = personInfoMap.get(personInfo.getCaseId());
                    personInfoTopyList2.addAll(personList);
                }
                personInfoMap.put(personInfo.getCaseId(), personInfoTopyList2);
            }
        }

        if (CollectionUtils.isNotEmpty(integrityCaseList)) {
            for (IntegrityCase integrityCase : integrityCaseList) {
                LambdaQueryWrapper<IntegrityCase> caseWrapper = new LambdaQueryWrapper<>();
                caseWrapper.eq(IntegrityCase::getTitle, integrityCase.getTitle());
                List<IntegrityCase> countList = iIntegrityCaseService.list(caseWrapper);
                if (CollectionUtils.isNotEmpty(countList)) {
                    iIntegrityCaseService.saveOrUpdate(integrityCase);
                } else {
                    iIntegrityCaseService.save(integrityCase);
                }
                List<PersonInfo> list = personInfoMap.get(integrityCase.getId());
                List<PersonInfo> personInfoArrayList = new ArrayList<>();
                if (CollectionUtils.isNotEmpty(list)) {
                    for (PersonInfo personInfoTopy : list) {
                        PersonInfo personInfo = new PersonInfo();
                        BeanUtil.copyProperties(personInfoTopy, personInfo);
                        personInfoArrayList.add(personInfo);
                        iPersonInfoService.queryCompany(personInfo);
                        personInfo.setCaseId(integrityCase.getId());
                        personInfo.setAcademicianTitle(AcademicianEnum.RESEARCH_INTEGRITY.getCode());
                        personInfo.setAcademicianTitleValue(AcademicianEnum.RESEARCH_INTEGRITY.getValue());
                    }
                    iPersonInfoService.verifyDuplicateNamesAndSaveOrUpdate(personInfoArrayList);
                }
            }
        }

        return respJson(CommonEnum.SUCCESS);
    }

    @PostMapping("/getIntegrityCase")
    public String getIntegrityCase(@RequestBody String data) {
        if (StringUtils.isBlank(data)) {
            return respJson(CommonEnum.PARAM_NULL_ERROR);
        }
        JSONObject jsonObject = JSON.parseObject(data);

        if (jsonObject.containsKey("fileName") && StringUtils.isNotBlank(jsonObject.getString("fileName"))) {
            String fileName = jsonObject.getString("fileName");
            String fileNamesuffix = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
            if (!StringUtils.equalsAny(fileNamesuffix, "xlsx", "xls")) {
                return respJson(CommonEnum.PARAM_ERROR, "导出excel的文件名称后缀不正确，后缀应该为xlsx或xls ");
            }
        }
        integrityCaseTask.submit(jsonObject);
        return respJson(CommonEnum.SUCCESS);
    }


    /**
     * 通过id查询
     */
    @GetMapping("/getById/{id}")
    public String getById(@PathVariable(value = "id") Integer id) {
        return respJson(CommonEnum.SUCCESS, iIntegrityCaseService.getById(id));
    }

    /**
     * 新增
     */
    @PostMapping("/save")
    public String save(@RequestBody IntegrityCase integrityCase) {
        iIntegrityCaseService.save(integrityCase);
        return respJson(CommonEnum.SUCCESS);
    }

    /**
     * 通过id删除
     */
    @DeleteMapping("/deleteById/{id}")
    public String delete(@PathVariable(value = "id") String ids) {
        String[] idsStrs = ids.split(",");
        for (String id : idsStrs) {
            iIntegrityCaseService.removeById(Integer.parseInt(id));
        }
        return respJson(CommonEnum.SUCCESS);
    }

    /**
     * 修改
     */
    @PutMapping("/update")
    public String updateById(@RequestBody IntegrityCase integrityCase) {
        iIntegrityCaseService.updateById(integrityCase);
        return respJson(CommonEnum.SUCCESS);
    }


    /**
     * 查询列表
     */
    @PostMapping("/list")
    public String list(@RequestBody IntegrityCaseReqVo integrityCase) {
        final LambdaQueryWrapper<IntegrityCase> lambda = new QueryWrapper<IntegrityCase>().lambda();
        this.buildCondition(lambda, integrityCase);
        return respJson(CommonEnum.SUCCESS, iIntegrityCaseService.list(lambda));
    }

    /**
     * 分页查询
     */
    @PostMapping("/page")
    public String page(@RequestBody IntegrityCaseReqVo pageParam) {
        final LambdaQueryWrapper<IntegrityCase> lambda = new QueryWrapper<IntegrityCase>().lambda();
        this.buildCondition(lambda, pageParam);
        final IPage<IntegrityCase> page = iIntegrityCaseService.page(new Page<>(Constants.PAGE_NO, Constants.PAGE_SIZE), lambda);
        return respJson(CommonEnum.SUCCESS, page);
    }


    /**
     * 构造查询条件
     *
     * @param lambda
     * @param param
     */
    private void buildCondition(LambdaQueryWrapper<IntegrityCase> lambda, IntegrityCaseReqVo param) {
        if (null != param.getId()) {
            lambda.eq(IntegrityCase::getId, param.getId());
        }
        if (null != param.getFirstAuthor()) {
            lambda.eq(IntegrityCase::getFirstAuthor, param.getFirstAuthor());
        }
        if (!StringUtils.isEmpty(param.getAndFirstAuthor())) {
            lambda.eq(IntegrityCase::getAndFirstAuthor, param.getAndFirstAuthor());
        }
        if (!StringUtils.isEmpty(param.getSecondAuthor())) {
            lambda.eq(IntegrityCase::getSecondAuthor, param.getSecondAuthor());
        }
        if (!StringUtils.isEmpty(param.getThirdAuthor())) {
            lambda.eq(IntegrityCase::getThirdAuthor, param.getThirdAuthor());
        }
        if (!StringUtils.isEmpty(param.getFourAuthor())) {
            lambda.eq(IntegrityCase::getFourAuthor, param.getFourAuthor());
        }
        if (!StringUtils.isEmpty(param.getFiveAuthor())) {
            lambda.eq(IntegrityCase::getFiveAuthor, param.getFiveAuthor());
        }
        if (!StringUtils.isEmpty(param.getSixAuthor())) {
            lambda.eq(IntegrityCase::getSixAuthor, param.getSixAuthor());
        }
        if (!StringUtils.isEmpty(param.getFirstReportAuthor())) {
            lambda.eq(IntegrityCase::getFirstReportAuthor, param.getFirstReportAuthor());
        }
        if (!StringUtils.isEmpty(param.getOtherAuthor())) {
            lambda.eq(IntegrityCase::getOtherAuthor, param.getOtherAuthor());
        }
        if (!StringUtils.isEmpty(param.getDoi())) {
            lambda.eq(IntegrityCase::getDoi, param.getDoi());
        }
        if (!StringUtils.isEmpty(param.getTitle())) {
            lambda.eq(IntegrityCase::getTitle, param.getTitle());
        }
        if (!StringUtils.isEmpty(param.getNotifySource())) {
            lambda.eq(IntegrityCase::getNotifySource, param.getNotifySource());
        }
        if (!CollectionUtils.isEmpty(param.getNotifyDateList())) {
            lambda.ge(IntegrityCase::getNotifyDate, param.getNotifyDateList().get(0));
            lambda.le(IntegrityCase::getNotifyDate, param.getNotifyDateList().get(1));
        }
        if (!StringUtils.isEmpty(param.getNotifyLink())) {
            lambda.eq(IntegrityCase::getNotifyLink, param.getNotifyLink());
        }
        if (!StringUtils.isEmpty(param.getHandleResult())) {
            lambda.eq(IntegrityCase::getHandleResult, param.getHandleResult());
        }
        if (!CollectionUtils.isEmpty(param.getCreateTimeList())) {
            lambda.ge(IntegrityCase::getCreateTime, param.getCreateTimeList().get(0));
            lambda.le(IntegrityCase::getCreateTime, param.getCreateTimeList().get(1));
        }
        if (!StringUtils.isEmpty(param.getCreateUser())) {
            lambda.eq(IntegrityCase::getCreateUser, param.getCreateUser());
        }
        if (!CollectionUtils.isEmpty(param.getUpdateTimeList())) {
            lambda.ge(IntegrityCase::getUpdateTime, param.getUpdateTimeList().get(0));
            lambda.le(IntegrityCase::getUpdateTime, param.getUpdateTimeList().get(1));
        }
        if (!StringUtils.isEmpty(param.getUpdateUser())) {
            lambda.eq(IntegrityCase::getUpdateUser, param.getUpdateUser());
        }
        lambda.orderBy(true, false, IntegrityCase::getId);
    }


    /**
     * 请求model
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    private static class IntegrityCaseReqVo extends IntegrityCase {
        private List<String> notifyDateList; // 通报日期起止
        private List<String> createTimeList; // 创建时间起止
        private List<String> updateTimeList; // 更新时间起止
    }


}
